﻿//#define _CRT_SECURE_NO_WARNINGS
// C/C++ 标准库学习网站：https://legacy.cplusplus.com
// C/C++ 参考学习网站：https://zh.cppreference.com/w/cpp
// C/C++ 微软(Visual Studio)中文学习网站：https://learn.microsoft.com/zh-cn/cpp/cpp/?view=msvc-170
// OpenGl 学习网站：https://docs.gl/
#include "common.h" // 包含预编译头文件

#include "MyWindow.h"


void MyWindow::onCentralWidgetContextMenuRequested()
{
    QMenu menu(this);

    // 使用QTextCodec进行手动转码
    //QTextCodec* codec = QTextCodec::codecForName("UTF-8");
    QAction* enableAll = menu.addAction(u8"打开文件");
    QAction* selectedAction = menu.exec(QCursor::pos());
    if (selectedAction == enableAll)
        openFileSlot();
}

void MyWindow::initOpenFileConnectSlot()
{
    // 音频操作中的错误处理
    connect(my_player, &MusicPlayer::audio_error, this, &MyWindow::audioErrorSlot, Qt::QueuedConnection);


    // 重置按钮
    connect(ui->pushButton_reset, &QPushButton::clicked, this, &MyWindow::resetSlot);


    // 进度条位置
    connect(ui->horizontalSlider, &QSlider::valueChanged, this, &MyWindow::currentTimeSlot);


    // 音调控制
    connect(ui->verticalSliderPitch, &QSlider::valueChanged, this, &MyWindow::setPitchSlot);
    connect(ui->doubleSpinBoxPitch, &QDoubleSpinBox::valueChanged,
        [this]() {
            ui->verticalSliderPitch->setValue(ui->doubleSpinBoxPitch->value() * 100);
            //setPitchSlot();
        });

    // 音率控制
    connect(ui->verticalSliderRate, &QSlider::valueChanged, this, &MyWindow::setRateSlot);
    connect(ui->doubleSpinBoxRate, &QDoubleSpinBox::valueChanged,
        [this]() {
            ui->verticalSliderRate->setValue(ui->doubleSpinBoxRate->value() * 100);
            //setRateSlot();
        });

    if (is_ALC_EXT_EFX_supported) {
        // 添加 groupBoxReverb 右键菜单支持
        ui->groupBoxReverb->setContextMenuPolicy(Qt::CustomContextMenu);
        connect(ui->groupBoxReverb, &QGroupBox::customContextMenuRequested, this, &MyWindow::onGroupBoxReverbContextMenuRequested);
        ui->checkBox_density->setEnabled(true);
        ui->checkBox_diffusion->setEnabled(true);
        ui->checkBox_gain->setEnabled(true);
        ui->checkBox_decay_time->setEnabled(true);
        ui->checkBox_gainhf->setEnabled(true);
        ui->checkBox_decay_hfratio->setEnabled(true);
        ui->checkBox_reflections_gain->setEnabled(true);
        ui->checkBox_reflections_delay->setEnabled(true);
        ui->checkBox_late_reverb_gain->setEnabled(true);
        connect(ui->checkBox_density, &QCheckBox::toggled, this, &MyWindow::setDensitySlot);
        connect(ui->checkBox_density, &QCheckBox::toggled, this, &MyWindow::setDiffusionSlot);
        connect(ui->checkBox_diffusion, &QCheckBox::toggled, this, &MyWindow::setDiffusionSlot);
        connect(ui->checkBox_gain, &QCheckBox::toggled, this, &MyWindow::setGainSlot);
        connect(ui->checkBox_gainhf, &QCheckBox::toggled, this, &MyWindow::setGainHFSlot);
        connect(ui->checkBox_decay_time, &QCheckBox::toggled, this, &MyWindow::setGainDecayTimeSlot);
        connect(ui->checkBox_decay_hfratio, &QCheckBox::toggled, this, &MyWindow::setDecayHFRatioSlot);
        connect(ui->checkBox_reflections_gain, &QCheckBox::toggled, this, &MyWindow::setReflectionsGainSlot);
        connect(ui->checkBox_reflections_delay, &QCheckBox::toggled, this, &MyWindow::setReflectionsDelaySlot);
        connect(ui->checkBox_late_reverb_gain, &QCheckBox::toggled, this, &MyWindow::setLateReverbGainSlot);
        // 安装事件过滤器，使 frame_1 到 frame_9 支持右键菜单
        ui->frame_1->installEventFilter(this);
        ui->frame_2->installEventFilter(this);
        ui->frame_3->installEventFilter(this);
        ui->frame_4->installEventFilter(this);
        ui->frame_5->installEventFilter(this);
        ui->frame_6->installEventFilter(this);
        ui->frame_7->installEventFilter(this);
        ui->frame_8->installEventFilter(this);
        ui->frame_9->installEventFilter(this);
        // 给 dail 控件也安装事件过滤器
        ui->dial_density->installEventFilter(this);
        ui->dial_diffusion->installEventFilter(this);
        ui->dial_gain->installEventFilter(this);
        ui->dial_gainhf->installEventFilter(this);
        ui->dial_decay_time->installEventFilter(this);
        ui->dial_decay_hfratio->installEventFilter(this);
        ui->dial_reflections_gain->installEventFilter(this);
        ui->dial_reflections_delay->installEventFilter(this);
        ui->dial_late_reverb_gain->installEventFilter(this);
    }

    // 声道控制
    connect(ui->radioButtonStereo, &QRadioButton::toggled, this, &MyWindow::ChoiceButtonSlot);
    connect(ui->radioButtonSet, &QRadioButton::toggled, this, &MyWindow::ChoiceButtonSlot);
    // 监听器坐标变化控制
    connect(ui->horizontalSlider_listenerX, &QSlider::valueChanged, this, &MyWindow::setListenerSlot);
    connect(ui->horizontalSlider_listenerY, &QSlider::valueChanged, this, &MyWindow::setListenerSlot);
    connect(ui->horizontalSlider_listenerZ, &QSlider::valueChanged, this, &MyWindow::setListenerSlot);
    connect(ui->spinBox_listenerX, &QSpinBox::valueChanged, this, &MyWindow::setListenerXSlot);
    connect(ui->spinBox_listenerY, &QSpinBox::valueChanged, this, &MyWindow::setListenerYSlot);
    connect(ui->spinBox_listenerZ, &QSpinBox::valueChanged, this, &MyWindow::setListenerZSlot);

    connect(ui->radioButtonDefine, &QRadioButton::clicked, this, &MyWindow::showCoordWindowSlot);
    //connect(timerCoord, &QTimer::timeout, this, &MyWindow::setVariableCoordSlot);
    connect(coord_window->getUi().pushButtonSure, &QPushButton::clicked,
        [this]() {
            if (!my_player)
                return;
            my_coord_thread->startThread(coord_window->getUi().spinBoxTimeSet->value());
        });


    // 均衡器
    connect(ui->verticalSlider_f62, &QSlider::valueChanged, this, &MyWindow::setF62Slot);
    connect(ui->verticalSlider_f125, &QSlider::valueChanged, this, &MyWindow::setF125Slot);
    connect(ui->verticalSlider_f250, &QSlider::valueChanged, this, &MyWindow::setF250Slot);
    connect(ui->verticalSlider_f500, &QSlider::valueChanged, this, &MyWindow::setF500Slot);
    connect(ui->verticalSlider_f1000, &QSlider::valueChanged, this, &MyWindow::setF1000Slot);
    connect(ui->verticalSlider_f2000, &QSlider::valueChanged, this, &MyWindow::setF2000Slot);
    connect(ui->verticalSlider_f4000, &QSlider::valueChanged, this, &MyWindow::setF4000Slot);
    connect(ui->verticalSlider_f8000, &QSlider::valueChanged, this, &MyWindow::setF8000Slot);
    connect(ui->verticalSlider_f16000, &QSlider::valueChanged, this, &MyWindow::setF16000Slot);
    connect(ui->verticalSlider_f62, &QSlider::sliderReleased, this, &MyWindow::resetFiltersSlot);
    connect(ui->verticalSlider_f125, &QSlider::sliderReleased, this, &MyWindow::resetFiltersSlot);
    connect(ui->verticalSlider_f250, &QSlider::sliderReleased, this, &MyWindow::resetFiltersSlot);
    connect(ui->verticalSlider_f500, &QSlider::sliderReleased, this, &MyWindow::resetFiltersSlot);
    connect(ui->verticalSlider_f1000, &QSlider::sliderReleased, this, &MyWindow::resetFiltersSlot);
    connect(ui->verticalSlider_f2000, &QSlider::sliderReleased, this, &MyWindow::resetFiltersSlot);
    connect(ui->verticalSlider_f4000, &QSlider::sliderReleased, this, &MyWindow::resetFiltersSlot);
    connect(ui->verticalSlider_f8000, &QSlider::sliderReleased, this, &MyWindow::resetFiltersSlot);
    connect(ui->verticalSlider_f16000, &QSlider::sliderReleased, this, &MyWindow::resetFiltersSlot);

    ChoiceButtonSlot(); // 设置默认声道
}

void MyWindow::audioErrorSlot(const std::string& msg)
{
    qDebug() << "Audio error: " << msg;
    ui->statusBar->showMessage(QString("Audio error: ") + QString::fromStdString(msg));
    //qDebug() << error;
    bool playOrPause = my_player->is_playing;
    my_player->pause();
    openFileSlot(true);
    my_player->seek_to_position(ui->horizontalSlider->value() * 1000.0);
    if (playOrPause)
        my_player->play();
}

void MyWindow::playSlot()
{
    if (!my_player)
        return;

    my_player->play();

    if (ui->radioButtonDefine->isChecked())
        my_coord_thread->startThread(coord_window->getUi().spinBoxTimeSet->value());
}

void MyWindow::pauseSlot()
{
    if (my_player)
        my_player->pause();
    my_coord_thread->stopThread();
}

void MyWindow::recordingSlot()
{
    if (recording_window && !recording_window->isVisible()) {
        // 保存窗口不可见
        delete recording_window;
        recording_window = nullptr;
    }
    else if (recording_window) {
        // 保存窗口已打开
        recording_window->show();
        return;
    }
    recording_window = new RecordingWindow();
    recording_window->show();
}

void MyWindow::resetSlot()
{
    bool playOrPause = false;
    if (my_player) {
        playOrPause = my_player->is_playing;
        my_player->pause();
    }

    // SoundTouch 重置
    sliderSpeed->setValue(100);
    ui->verticalSliderPitch->setValue(100);
    ui->verticalSliderRate->setValue(100);
    //ui->doubleSpinBoxPitch->setValue(1.00);
    //ui->doubleSpinBoxRate->setValue(1.00);

    // OpenAL 重置
    sliderVolume->setValue(100);
    ui->dial_gain->setValue(0);
    ui->dial_gainhf->setValue(0);
    ui->dial_decay_time->setValue(1);
    ui->dial_density->setValue(0);
    ui->dial_diffusion->setValue(0);
    ui->dial_decay_hfratio->setValue(20);
    ui->dial_reflections_gain->setValue(0);
    ui->dial_reflections_delay->setValue(0);
    ui->dial_late_reverb_gain->setValue(0);
    ui->horizontalSlider_listenerX->setValue(0);
    ui->horizontalSlider_listenerY->setValue(0);
    ui->horizontalSlider_listenerZ->setValue(0);

    // 均衡器重置
    ui->verticalSlider_f62->setValue(0);
    ui->verticalSlider_f125->setValue(0);
    ui->verticalSlider_f250->setValue(0);
    ui->verticalSlider_f500->setValue(0);
    ui->verticalSlider_f1000->setValue(0);
    ui->verticalSlider_f2000->setValue(0);
    ui->verticalSlider_f4000->setValue(0);
    ui->verticalSlider_f8000->setValue(0);
    ui->verticalSlider_f16000->setValue(0);

    if (playOrPause)
        my_player->play();
}

void MyWindow::seekingSlot()
{
    if (my_player)
        my_player->seeking(ui->horizontalSlider->value() * 1000);
}

void MyWindow::seekToSlot()
{
    if (my_player) {
        //alSourcef(my_player->al_source, AL_PITCH, 1000.0f); // 设置播放速度为100%
        //alSourcePlay(my_player->al_source);
        my_player->seek_to_position(ui->horizontalSlider->value() * 1000);
        //alSourcef(my_player->al_source, AL_PITCH, 1.0f);
    }
}

void MyWindow::setAudioPositionSlot(int64_t position)
{
    /*qDebug() << "Slider length: " << ui->horizontalSlider->maximum();
    qDebug() << "Audio position: " << position;*/
    // 只有未拖动时才自动更新进度条
    if (!slider_is_pressed)
        ui->horizontalSlider->setValue(position);
}

void MyWindow::audioEndSlot()
{
    //ui->pushButton_play->setEnabled(true);
    //my_player->seek_to_position(0);
    my_player->pause();
    qDebug() << "Audio end";
}

//void MyWindow::setVolumeSlot()
//{
//    int volume = ui->horizontalSlider_volume->value();
//    my_player->set_volume(volume);
//}

void MyWindow::currentTimeSlot()
{
    int currentTime =  ui->horizontalSlider->value(); // 毫秒数
    QString durationText = QTime(0, 0, 0, 0).addMSecs(currentTime).toString("hhh:mm:ss:zzz");
    durationText.chop(1); // 去掉最后一个 z
    // 格式化显示总时长，保留两位小数
    ui->labelTimeCurrent->setText(durationText);
}

void MyWindow::setPitchSlot()
{
    float pitch = ui->verticalSliderPitch->value() / 100.0f;
    my_player->set_audio_pitch(pitch);
    ui->doubleSpinBoxPitch->setValue(pitch);
}

void MyWindow::setRateSlot()
{
    float rate = ui->verticalSliderRate->value() / 100.0f;
    my_player->set_audio_rate(rate);
    ui->doubleSpinBoxRate->setValue(rate);
}

void MyWindow::setListenerSlot()
{
    int posX = ui->horizontalSlider_listenerX->value();
    int posY = ui->horizontalSlider_listenerY->value();
    int posZ = ui->horizontalSlider_listenerZ->value();
    my_player->set_listener_coordinate(posX, posY, posZ);

    // 更新显示
    //ui->spinBox_listenerX->setStyleSheet(""); // 移除样式表
    ui->spinBox_listenerX->setValue(posX);
    ui->spinBox_listenerY->setValue(posY);
    ui->spinBox_listenerZ->setValue(posZ);
}

void MyWindow::setListenerXSlot()
{
    int posX = ui->spinBox_listenerX->value();
    my_player->set_listener_coordinate(posX,
        ui->horizontalSlider_listenerY->value(),
        ui->horizontalSlider_listenerZ->value());

    // 更新 X 轴显示
    ui->horizontalSlider_listenerX->setValue(posX);
}

void MyWindow::setListenerYSlot()
{
    int posY = ui->spinBox_listenerY->value();
    my_player->set_listener_coordinate(ui->horizontalSlider_listenerX->value(),
        posY, ui->horizontalSlider_listenerZ->value());

    // 更新 Y 轴显示
    ui->horizontalSlider_listenerY->setValue(posY);
}

void MyWindow::setListenerZSlot()
{
    int posZ = ui->spinBox_listenerZ->value();
    my_player->set_listener_coordinate(ui->horizontalSlider_listenerX->value(),
        ui->horizontalSlider_listenerY->value(), posZ);

    // 更新 Z 轴显示
    ui->horizontalSlider_listenerZ->setValue(posZ);
}

template<typename T>
void MyWindow::run_in_subthread(T* self, void (T::* func)())
{
    std::thread sub_thread;
    sub_thread = std::thread(func, self);
    //sub_thread.detach();
    if (sub_thread.joinable())
        sub_thread.join();
}

void MyWindow::show_coord_window()
{
    /*bool playOrPause = false;
    if (my_player) {
        playOrPause = my_player->is_playing;
        my_player->pause();
        my_player->soundTouch.setChannels(1);
        my_player->reset_p_swr_context_SoundTouch(AV_CHANNEL_LAYOUT_MONO);
        my_player->reset_p_swr_context_output(AV_CHANNEL_LAYOUT_MONO);
        my_player->seek_to_position(ui->horizontalSlider->value() * 1000);
    }
    coord_window->show();
    if (playOrPause)
        my_player->play();
    my_coord_thread->startThread(coord_window->getUi().spinBoxTimeSet->value());*/
}

void MyWindow::showCoordWindowSlot()
{
    //run_in_subthread(this, &MyWindow::show_coord_window);
    bool playOrPause = false;
    if (my_player) {
        playOrPause = my_player->is_playing;
        my_player->pause();
        my_player->soundTouch.setChannels(1);
        my_player->reset_p_swr_context_SoundTouch(AV_CHANNEL_LAYOUT_MONO);
        my_player->reset_p_swr_context_output(AV_CHANNEL_LAYOUT_MONO);
        my_player->seek_to_position(ui->horizontalSlider->value() * 1000);
    }
    coord_window->show();
    if (playOrPause)
        my_player->play();
    my_coord_thread->startThread(coord_window->getUi().spinBoxTimeSet->value());
}

/*
void MyWindow::setVariableCoordSlot()
{
    //if (!var_listener_coord.flag_x ||
    //    !var_listener_coord.flag_y ||
    //    !var_listener_coord.flag_z)
    //    return;

//start:
    if (var_listener_coord.flag_x > 0)
        var_listener_coord.x += coord_window->getUi().spinBoxPosX->value();
    else if (var_listener_coord.flag_x < 0)
        var_listener_coord.x -= coord_window->getUi().spinBoxPosX->value();

    if (var_listener_coord.flag_y > 0)
        var_listener_coord.y += coord_window->getUi().spinBoxPosY->value();
    else if (var_listener_coord.flag_y < 0)
        var_listener_coord.y -= coord_window->getUi().spinBoxPosY->value();

    if (var_listener_coord.flag_z > 0)
        var_listener_coord.z += coord_window->getUi().spinBoxPosZ->value();
    else if (var_listener_coord.flag_z < 0)
        var_listener_coord.z -= coord_window->getUi().spinBoxPosZ->value();

    if (var_listener_coord.x > 1000 ||
        var_listener_coord.x < -1000) {
        var_listener_coord.flag_x = -var_listener_coord.flag_x;
        if (var_listener_coord.flag_x > 0)
            var_listener_coord.x += coord_window->getUi().spinBoxPosX->value();
        else if (var_listener_coord.flag_x < 0)
            var_listener_coord.x -= coord_window->getUi().spinBoxPosX->value();
        //goto start;
    }
    if (var_listener_coord.y > 1000 ||
        var_listener_coord.y < -1000) {
        var_listener_coord.flag_y = -var_listener_coord.flag_y;
        if (var_listener_coord.flag_y > 0)
            var_listener_coord.y += coord_window->getUi().spinBoxPosY->value();
        else if (var_listener_coord.flag_y < 0)
            var_listener_coord.y -= coord_window->getUi().spinBoxPosY->value();
        //goto start;
    }
    if (var_listener_coord.z > 1000 ||
        var_listener_coord.z < -1000) {
        var_listener_coord.flag_z = -var_listener_coord.flag_z;
        if (var_listener_coord.flag_z > 0)
            var_listener_coord.z += coord_window->getUi().spinBoxPosZ->value();
        else if (var_listener_coord.flag_z < 0)
            var_listener_coord.z -= coord_window->getUi().spinBoxPosZ->value();
        //goto start;
    }
    //qDebug() << "Listener coord: (" <<
    //    var_listener_coord.x << ", " <<
    //    var_listener_coord.y << ", " <<
    //    var_listener_coord.z << ")";
    my_player->set_listener_coordinate(var_listener_coord.x,
        var_listener_coord.y,
        var_listener_coord.z);
}
*/

void MyWindow::ChoiceButtonSlot()
{
    if (ui->radioButtonStereo->isChecked()) {
        my_player->soundTouch.setChannels(2);
        my_player->reset_p_swr_context_SoundTouch(AV_CHANNEL_LAYOUT_STEREO);
        my_player->reset_p_swr_context_output(AV_CHANNEL_LAYOUT_STEREO);
    }
    else if (ui->radioButtonSet->isChecked()) {
        my_player->soundTouch.setChannels(1);
        my_player->reset_p_swr_context_SoundTouch(AV_CHANNEL_LAYOUT_MONO);
        my_player->reset_p_swr_context_output(AV_CHANNEL_LAYOUT_MONO);
        setListenerSlot();
    }
    my_player->seek_to_position(ui->horizontalSlider->value() * 1000);
    my_coord_thread->stopThread();
    coord_window->hide();
}


void MyWindow::onGroupBoxReverbContextMenuRequested(const QPoint& pos)
{
    QMenu menu(this);

    // 使用QTextCodec进行手动转码
    //QTextCodec* codec = QTextCodec::codecForName("UTF-8");
    QAction* enableAll = menu.addAction(u8"开启所有效果");
    QAction* disableAll = menu.addAction(u8"关闭所有效果");
    QAction* selectedAction = menu.exec(ui->groupBoxReverb->mapToGlobal(pos));
    if (selectedAction == enableAll) {
        enableAllReverbEffects();
    }
    else if (selectedAction == disableAll) {
        disableAllReverbEffects();
    }
}

void MyWindow::setAllCurrentReverbEffects()
{
    // 声音效果
    if (is_ALC_EXT_EFX_supported) {
        my_player->update_affects(my_player, &MusicPlayer::set_gain, ui->doubleSpinBoxGain->value());
        my_player->update_affects(my_player, &MusicPlayer::set_gainhf, ui->doubleSpinBoxGainHF->value());
        my_player->update_affects(my_player, &MusicPlayer::set_decay_time, ui->doubleSpinBoxDecayTime->value());
        my_player->update_affects(my_player, &MusicPlayer::set_density, ui->doubleSpinBoxDensity->value());
        my_player->update_affects(my_player, &MusicPlayer::set_diffusion, ui->doubleSpinBoxDiffusion->value());
        my_player->update_affects(my_player, &MusicPlayer::set_decay_hfratio, ui->doubleSpinBoxDecayHFRatio->value());
        my_player->update_affects(my_player, &MusicPlayer::set_reflections_gain, ui->doubleSpinBoxReflectionsGain->value());
        my_player->update_affects(my_player, &MusicPlayer::set_reflections_delay, ui->doubleSpinBoxReflectionsDelay->value());
        my_player->update_affects(my_player, &MusicPlayer::set_late_reverb_gain, ui->doubleSpinBoxLateReverbGain->value());
    }
}

void MyWindow::enableAllReverbEffects()
{
    ui->checkBox_density->setChecked(true);
    ui->checkBox_diffusion->setChecked(true);
    ui->checkBox_gain->setChecked(true);
    ui->checkBox_decay_time->setChecked(true);
    ui->checkBox_gainhf->setChecked(true);
    ui->checkBox_decay_hfratio->setChecked(true);
    ui->checkBox_reflections_gain->setChecked(true);
    ui->checkBox_reflections_delay->setChecked(true);
    ui->checkBox_late_reverb_gain->setChecked(true);
}

void MyWindow::disableAllReverbEffects()
{
    ui->checkBox_density->setChecked(false);
    ui->checkBox_diffusion->setChecked(false);
    ui->checkBox_gain->setChecked(false);
    ui->checkBox_decay_time->setChecked(false);
    ui->checkBox_gainhf->setChecked(false);
    ui->checkBox_decay_hfratio->setChecked(false);
    ui->checkBox_reflections_gain->setChecked(false);
    ui->checkBox_reflections_delay->setChecked(false);
    ui->checkBox_late_reverb_gain->setChecked(false);
}


// 混响效果
void MyWindow::setDensitySlot()
{
    if (ui->checkBox_density->checkState() == Qt::Checked) {
        ui->dial_density->setEnabled(true);
        ui->doubleSpinBoxDensity->setEnabled(true);
        my_player->update_affects(my_player, &MusicPlayer::set_density, ui->dial_density->value() / 100.0f);
        connect(ui->dial_density, &QDial::valueChanged,
            [this](int intValue) {
                ui->doubleSpinBoxDensity->setValue(intValue / 100.0f);
                my_player->update_affects(my_player, &MusicPlayer::set_density, intValue / 100.0f);
            });
        connect(ui->doubleSpinBoxDensity, &QDoubleSpinBox::valueChanged,
            [this](double doubleValue) {
                ui->dial_density->setValue(doubleValue * 100);
                my_player->update_affects(my_player, &MusicPlayer::set_density, doubleValue * 100);
            });
    }
    else {
        ui->dial_density->setEnabled(false);
        ui->doubleSpinBoxDensity->setEnabled(false);
        my_player->update_affects(my_player, &MusicPlayer::set_density, 0.0f);
    }
}

void MyWindow::setDiffusionSlot()
{
    if (ui->checkBox_diffusion->checkState() == Qt::Checked) {
        ui->dial_diffusion->setEnabled(true);
        ui->doubleSpinBoxDiffusion->setEnabled(true);
        my_player->update_affects(my_player, &MusicPlayer::set_diffusion, ui->dial_diffusion->value() / 100.0f);
        connect(ui->dial_diffusion, &QDial::valueChanged,
            [this](int intValue) {
                ui->doubleSpinBoxDiffusion->setValue(intValue / 100.0f);
                my_player->update_affects(my_player, &MusicPlayer::set_diffusion, intValue / 100.0f);
            });
        connect(ui->doubleSpinBoxDiffusion, &QDoubleSpinBox::valueChanged,
            [this](double doubleValue) {
                ui->dial_diffusion->setValue(doubleValue * 100);
                my_player->update_affects(my_player, &MusicPlayer::set_diffusion, doubleValue * 100);

            });
    }
    else {
        ui->dial_diffusion->setEnabled(false);
        ui->doubleSpinBoxDiffusion->setEnabled(false);
        my_player->update_affects(my_player, &MusicPlayer::set_diffusion, 0.0f);
    }
}

void MyWindow::setGainSlot()
{
    if (ui->checkBox_gain->checkState() == Qt::Checked) {
        ui->dial_gain->setEnabled(true);
        ui->doubleSpinBoxGain->setEnabled(true);
        my_player->update_affects(my_player, &MusicPlayer::set_gain, ui->dial_gain->value() / 100.0f);
        connect(ui->dial_gain, &QDial::valueChanged,
            [this](int intValue) {
                ui->doubleSpinBoxGain->setValue(intValue / 100.0f);
                my_player->update_affects(my_player, &MusicPlayer::set_gain, intValue / 100.0f);
            });
        connect(ui->doubleSpinBoxGain, &QDoubleSpinBox::valueChanged,
            [this](double doubleValue) {
                ui->dial_gain->setValue(doubleValue * 100);
                my_player->update_affects(my_player, &MusicPlayer::set_gain, doubleValue * 100);

            });
    }
    else {
        ui->dial_gain->setEnabled(false);
        ui->doubleSpinBoxGain->setEnabled(false);
        my_player->update_affects(my_player, &MusicPlayer::set_gain, 0.0f);
    }
}

void MyWindow::setGainHFSlot()
{
    if (ui->checkBox_gainhf->checkState() == Qt::Checked) {
        ui->dial_gainhf->setEnabled(true);
        ui->doubleSpinBoxGainHF->setEnabled(true);
        my_player->update_affects(my_player, &MusicPlayer::set_gainhf, ui->dial_gainhf->value() / 100.0f);
        connect(ui->dial_gainhf, &QDial::valueChanged,
            [this](float intValue) {
                ui->doubleSpinBoxGainHF->setValue(intValue / 100.0);
                my_player->update_affects(my_player, &MusicPlayer::set_gainhf, intValue / 100.0);
            });
        connect(ui->doubleSpinBoxGainHF, &QDoubleSpinBox::valueChanged,
            [this](double doubleValue) {
                ui->dial_gainhf->setValue(doubleValue * 100);
                my_player->update_affects(my_player, &MusicPlayer::set_gainhf, doubleValue * 100);
            });
    }
    else {
        ui->dial_gainhf->setEnabled(false);
        ui->doubleSpinBoxGainHF->setEnabled(false);
        my_player->update_affects(my_player, &MusicPlayer::set_gainhf, 0.0f);
    }
}

void MyWindow::setGainDecayTimeSlot()
{
    if (ui->checkBox_decay_time->checkState() == Qt::Checked) {
        ui->dial_decay_time->setEnabled(true);
        ui->doubleSpinBoxDecayTime->setEnabled(true);
        my_player->update_affects(my_player, &MusicPlayer::set_decay_time, ui->dial_decay_time->value() / 10.0f);
        connect(ui->dial_decay_time, &QDial::valueChanged,
            [this](int intValue) {
                ui->doubleSpinBoxDecayTime->setValue(intValue / 10.0);
                my_player->update_affects(my_player, &MusicPlayer::set_decay_time, intValue / 10.0f);
            });
        connect(ui->doubleSpinBoxDecayTime, &QDoubleSpinBox::valueChanged,
            [this](double doubleValue) {
                ui->dial_decay_time->setValue(doubleValue * 10);
                my_player->update_affects(my_player, &MusicPlayer::set_decay_time, doubleValue * 10);
            });
    }
    else {
        ui->dial_decay_time->setEnabled(false);
        ui->doubleSpinBoxDecayTime->setEnabled(false);
        my_player->update_affects(my_player, &MusicPlayer::set_decay_time, 0.1f);
    }
}

void MyWindow::setDecayHFRatioSlot()
{
    if (ui->checkBox_decay_hfratio->checkState() == Qt::Checked) {
        ui->dial_decay_hfratio->setEnabled(true);
        ui->doubleSpinBoxDecayHFRatio->setEnabled(true);
        my_player->update_affects(my_player, &MusicPlayer::set_decay_hfratio, ui->dial_decay_hfratio->value() / 10.0f);
        connect(ui->dial_decay_hfratio, &QDial::valueChanged,
            [this](int intValue) {
                ui->doubleSpinBoxDecayHFRatio->setValue(intValue / 10.0);
                my_player->update_affects(my_player, &MusicPlayer::set_decay_hfratio, intValue / 10.0f);
            });
        connect(ui->doubleSpinBoxDecayHFRatio, &QDoubleSpinBox::valueChanged,
            [this](double doubleValue) {
                ui->dial_decay_hfratio->setValue(doubleValue * 10);
                my_player->update_affects(my_player, &MusicPlayer::set_decay_hfratio, doubleValue * 10);
            });
    }
    else {
        ui->dial_decay_hfratio->setEnabled(false);
        ui->doubleSpinBoxDecayHFRatio->setEnabled(false);
        my_player->update_affects(my_player, &MusicPlayer::set_decay_hfratio, 2.0f);
    }
}

void MyWindow::setReflectionsGainSlot()
{
    if (ui->checkBox_reflections_gain->checkState() == Qt::Checked) {
        ui->dial_reflections_gain->setEnabled(true);
        ui->doubleSpinBoxReflectionsGain->setEnabled(true);
        my_player->update_affects(my_player, &MusicPlayer::set_reflections_gain, ui->dial_reflections_gain->value() / 100.0f);
        connect(ui->dial_reflections_gain, &QDial::valueChanged,
            [this](int intValue) {
                ui->doubleSpinBoxReflectionsGain->setValue(intValue / 100.0);
                my_player->update_affects(my_player, &MusicPlayer::set_reflections_gain, intValue / 100.0f);
            });
        connect(ui->doubleSpinBoxReflectionsGain, &QDoubleSpinBox::valueChanged,
            [this](double doubleValue) {
                ui->dial_reflections_gain->setValue(doubleValue * 100);
                my_player->update_affects(my_player, &MusicPlayer::set_reflections_gain, doubleValue * 100);
            });
    }
    else {
        ui->dial_reflections_gain->setEnabled(false);
        ui->doubleSpinBoxReflectionsGain->setEnabled(false);
        my_player->update_affects(my_player, &MusicPlayer::set_reflections_gain, 0.0f);
    }
}

void MyWindow::setReflectionsDelaySlot()
{
    if (ui->checkBox_reflections_delay->checkState() == Qt::Checked) {
        ui->dial_reflections_delay->setEnabled(true);
        ui->doubleSpinBoxReflectionsDelay->setEnabled(true);
        my_player->update_affects(my_player, &MusicPlayer::set_reflections_delay, ui->dial_reflections_delay->value() / 100.0f);
        connect(ui->dial_reflections_delay, &QDial::valueChanged,
            [this](int intValue) {
                ui->doubleSpinBoxReflectionsDelay->setValue(intValue / 100.0);
                my_player->update_affects(my_player, &MusicPlayer::set_reflections_delay, intValue / 100.0f);
            });
        connect(ui->doubleSpinBoxReflectionsDelay, &QDoubleSpinBox::valueChanged,
            [this](double doubleValue) {
                ui->dial_reflections_delay->setValue(doubleValue * 100);
                my_player->update_affects(my_player, &MusicPlayer::set_reflections_delay, doubleValue * 100);
            });
    }
    else {
        ui->dial_reflections_delay->setEnabled(false);
        ui->doubleSpinBoxReflectionsDelay->setEnabled(false);
        my_player->update_affects(my_player, &MusicPlayer::set_reflections_delay, 0.00f);
    }
}

void MyWindow::setLateReverbGainSlot()
{
    if (ui->checkBox_late_reverb_gain->checkState() == Qt::Checked) {
        ui->dial_late_reverb_gain->setEnabled(true);
        ui->doubleSpinBoxLateReverbGain->setEnabled(true);
        my_player->update_affects(my_player, &MusicPlayer::set_late_reverb_gain, ui->dial_late_reverb_gain->value() / 100.0f);
        connect(ui->dial_late_reverb_gain, &QDial::valueChanged,
            [this](int intValue) {
                ui->doubleSpinBoxLateReverbGain->setValue(intValue / 100.0);
                my_player->update_affects(my_player, &MusicPlayer::set_late_reverb_gain, intValue / 100.0f);
            });
        connect(ui->doubleSpinBoxLateReverbGain, &QDoubleSpinBox::valueChanged,
            [this](double doubleValue) {
                ui->dial_late_reverb_gain->setValue(doubleValue * 100);
                my_player->update_affects(my_player, &MusicPlayer::set_late_reverb_gain, doubleValue * 100);
            });
    }
    else {
        ui->dial_late_reverb_gain->setEnabled(false);
        ui->doubleSpinBoxLateReverbGain->setEnabled(false);
        my_player->update_affects(my_player, &MusicPlayer::set_late_reverb_gain, 0.00f);
    }
}


// 均衡器
//extern MyFilter my_filters;
void MyWindow::setF62Slot(int value) {
    my_filters.f62 = value / 10.0f;
    //qDebug() << "F62: " << my_filters.f62;
    //resetFiltersSlot();
}

void MyWindow::setF125Slot(int value) {
    my_filters.f125 = value / 10.0f;
    //qDebug() << "F125: " << my_filters.f125;
    //resetFiltersSlot();
}

void MyWindow::setF250Slot(int value) {
    my_filters.f250 = value / 10.0f;
    //qDebug() << "F250: " << my_filters.f250;
    //resetFiltersSlot();
}

void MyWindow::setF500Slot(int value) {
    my_filters.f500 = value / 10.0f;
    //qDebug() << "F500: " << my_filters.f500;
    resetFiltersSlot();
}

void MyWindow::setF1000Slot(int value) {
    my_filters.f1000 = value / 10.0f;
    //qDebug() << "F1000: " << my_filters.f1000;
    //resetFiltersSlot();
}

void MyWindow::setF2000Slot(int value) {
    my_filters.f2000 = value / 10.0f;
    //qDebug() << "F2000: " << my_filters.f2000;
    //resetFiltersSlot();
}

void MyWindow::setF4000Slot(int value) {
    my_filters.f4000 = value / 10.0f;
    //qDebug() << "F4000: " << my_filters.f4000;
    //resetFiltersSlot();
}

void MyWindow::setF8000Slot(int value) {
    my_filters.f8000 = value / 10.0f;
    //qDebug() << "F8000: " << my_filters.f8000;
    resetFiltersSlot();
}

void MyWindow::setF16000Slot(int value) {
    my_filters.f16000 = value / 10.0f;
    //qDebug() << "F16000: " << my_filters.f16000;
    //resetFiltersSlot();
}

void MyWindow::resetFiltersSlot() {
    if (ui->radioButtonStereo->isChecked())
        my_player->my_ffmpeg->init_filters(AV_CHANNEL_LAYOUT_STEREO);
    else
        my_player->my_ffmpeg->init_filters();
}
